package cn.tedu.rms.reservation.service.impl;

import cn.tedu.rms.base.enums.ReservationEnum;
import cn.tedu.rms.base.enums.TablesStatus;
import cn.tedu.rms.base.exception.ServiceException;
import cn.tedu.rms.base.response.StatusCode;
import cn.tedu.rms.branch.mapper.BranchMapper;
import cn.tedu.rms.reservation.mapper.ReservationMapper;
import cn.tedu.rms.reservation.pojo.dto.ReservationQuery;
import cn.tedu.rms.reservation.pojo.dto.ReservationSaveParam;
import cn.tedu.rms.reservation.pojo.entity.Reservation;
import cn.tedu.rms.reservation.pojo.vo.ReservationVO;
import cn.tedu.rms.reservation.service.ReservationService;
import cn.tedu.rms.tables.mapper.TablesMapper;
import cn.tedu.rms.tables.pojo.dto.TablesQuery;
import cn.tedu.rms.tables.pojo.dto.TablesSaveParam;
import cn.tedu.rms.tables.pojo.entity.Tables;
import cn.tedu.rms.tables.pojo.vo.TablesVO;
import cn.tedu.rms.user.mapper.UserMapper;
import cn.tedu.rms.user.pojo.entity.User;
import cn.tedu.rms.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class ReservationServiceImpl implements ReservationService {
    @Autowired
    ReservationMapper reservationMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    TablesMapper tablesMapper;
    @Autowired
    BranchMapper branchMapper;


    @Override
    public List<ReservationVO> selectReservation(ReservationQuery reservationQuery) {
        log.debug("查询预约数据:参数={}",reservationQuery);
        List<ReservationVO> list=reservationMapper.selectReservation(reservationQuery);
        // 通过handleId查询处理人名称 加到list中
        for (ReservationVO reservationVO : list) {
            //补充分店名称
            reservationVO.setBranchName(branchMapper.selectById(reservationVO.getBranchId()).getName());

            log.debug("通过handleId查询处理人名称:参数={}",reservationVO.getHandleId());
            if (reservationVO.getHandleId()!=null){
                Long handleId=reservationVO.getHandleId();
                UserVO uservo=userMapper.selectUserById(handleId);
                String handleName=uservo.getUsername();
                reservationVO.setHandleName(handleName);
            }

        }
        return list;
    }

    @Override
    public void save(ReservationSaveParam reservationSaveParam) {
        log.debug("保存预约数据:参数={}",reservationSaveParam);
        // 通过参数是否有id 判断是新增还是修改
        Reservation reservation=new Reservation();
        BeanUtils.copyProperties(reservationSaveParam,reservation);
        log.debug("转换为实体对象:{}",reservation);
        if (reservation.getId()==null){
            log.debug("新增预约业务");
            // 根据传入的时间判断该餐桌是否被预约（预约时间段内 )
            Date date=reservation.getReservationTime();
            // 判断该时间属于什么时间分段
            int timeStatus = getTimeSegment(date);
            log.debug("判断该时间属于什么时间段:{}",timeStatus);
            // 根据时间段查询该时间段内是否有预约
            // 根据该时间段的 字段和餐桌id 查询餐桌该时间的预约状态
            // 1， 如果有预约，则不能新增预约，抛出异常
            // 2，如果没有预约，则可以新增预约
            TablesQuery tablesQuery=new TablesQuery();
            tablesQuery.setId(reservation.getTableId());
            tablesQuery.setStatus(TablesStatus.STATUS_ENABLED.getCode());
            // 通过id和状态查询
            List<TablesVO> list=tablesMapper.select(tablesQuery);
            TablesVO tablesVO=list.get(0);
            log.debug("通过id和状态查询:{}",tablesVO);
            switch (timeStatus){
                case 1:
                    if (TablesStatus.TIME_NUM_NO.getCode().equals(tablesVO.getTimeOne())){
                        log.debug("该时间段没有预约，可以新增预约");
                        break;
                    }else {
                        log.debug("该时间段有预约，不能新增预约");
                        throw new ServiceException(StatusCode.TIME_ALREADY_RESERVED);
                    }
                case 2:
                    if (TablesStatus.TIME_NUM_NO.getCode().equals(tablesVO.getTimeOne())){
                        log.debug("该时间段没有预约，可以新增预约");
                        break;
                    }else {
                        log.debug("该时间段有预约，不能新增预约");
                        throw new ServiceException(StatusCode.TIME_ALREADY_RESERVED);
                    }
                case 3:
                    if (TablesStatus.TIME_NUM_NO.getCode().equals(tablesVO.getTimeOne())){
                        log.debug("该时间段没有预约，可以新增预约");
                    }else {
                        log.debug("该时间段有预约，不能新增预约");
                        throw new ServiceException(StatusCode.TIME_ALREADY_RESERVED);
                    }
                case 4:
                    if (TablesStatus.TIME_NUM_NO.getCode().equals(tablesVO.getTimeOne())){
                        log.debug("该时间段没有预约，可以新增预约");
                    }else {
                        log.debug("该时间段有预约，不能新增预约");
                        throw new ServiceException(StatusCode.TIME_ALREADY_RESERVED);
                    }
                case 5:
                    if (TablesStatus.TIME_NUM_NO.getCode().equals(tablesVO.getTimeOne())){
                        log.debug("该时间段没有预约，可以新增预约");
                    }else {
                        log.debug("该时间段有预约，不能新增预约");
                        throw new ServiceException(StatusCode.TIME_ALREADY_RESERVED);
                    }
            }
            reservation.setCreateTime(new Date());
            // 设置新增的状态为发起状态
            reservation.setStatus(ReservationEnum.PENDING.getCode());
            reservationMapper.insert(reservation);
        }else {
            // 还需要进一步的判断，前端传入状态
            log.debug("修改,撤销预约业务");
            // 修改预约表的状态
            reservation.setUpdateTime(new Date());
            reservationMapper.update(reservation);
            // 设置需要更新的餐桌数据,公共部分
            Tables tables=new Tables();
            tables.setId(reservation.getTableId());
            tables.setUpdateTime(new Date());
            // 1. 当审核通过时50 ，需要：修改餐桌对应时间段的状态为已经预约1
            if (ReservationEnum.AUDITED.getCode().equals(reservation.getStatus())){
                log.debug("审核通过业务,当前预约状态：{}",reservation.getStatus());
                // 将通用的状态设置为已预约，方便对该餐桌是否有预约判断
                tables.setRepastStatus(TablesStatus.REPAST_RESERVED.getCode());
                // 设置餐桌对应时间段的状态为已经预约1
                int timeStatus = getTimeSegment(reservation.getReservationTime());
                switch (timeStatus){
                    case 1:
                        tables.setTimeOne(TablesStatus.TIME_NUM_YES.getCode());
                        break;
                    case 2:
                        tables.setTimeTwo(TablesStatus.TIME_NUM_YES.getCode());
                        break;
                    case 3:
                        tables.setTimeThree(TablesStatus.TIME_NUM_YES.getCode());
                        break;
                    case 4:
                        tables.setTimeFour(TablesStatus.TIME_NUM_YES.getCode());
                        break;
                    case 5:
                        tables.setTimeFive(TablesStatus.TIME_NUM_YES.getCode());
                       break;
                }
                // 更新餐桌的状态
                tablesMapper.update(tables);
            }else if (ReservationEnum.AFFIRM.getCode().equals(reservation.getStatus())){
                // 2. 当店员确认用户已到店 状态60 需要：修改餐桌对应时间段的预约状态为 预约状态1
                log.debug("店员确认用户已到店业务,当前预约状态：{}",reservation.getStatus());
                // 恢复餐桌预约状态为0 // 设置餐桌的就餐状态为就餐中
                int timeStatus = getTimeSegment(reservation.getReservationTime());
                log.debug("当前时间段：{}",timeStatus);
                //tables.setRepastStatus(TablesStatus.REPAST_RESERVED.getCode());
                log.debug("恢复餐桌就餐状态为就餐中");
                switch (timeStatus){
                    case 1:
                        tables.setTimeOne(TablesStatus.TIME_NUM_NO.getCode());
                        break;
                    case 2:
                        tables.setTimeTwo(TablesStatus.TIME_NUM_NO.getCode());
                        break;
                    case 3:
                        tables.setTimeThree(TablesStatus.TIME_NUM_NO.getCode());
                        break;
                    case 4:
                        tables.setTimeFour(TablesStatus.TIME_NUM_NO.getCode());
                        break;
                    case 5:
                        tables.setTimeFive(TablesStatus.TIME_NUM_NO.getCode());
                        break;
                }
                // 更新餐桌的状态
                tablesMapper.update(tables);
            }

        }

    }

    // 根据时间获取时间段
    public int  getTimeSegment(Date date) {
        int hour = date.getHours();
        int status=0;
        if (hour >= 0 && hour < 8) {
            //return "time_one";
            status= 1;
        } else if (hour >= 8 && hour < 12) {
            //return "time_two";
            status= 2;
        } else if (hour >= 12 && hour < 16) {
            //return "time_three";
            status= 3;
        } else if (hour >= 16 && hour < 20) {
            //return "time_four";
            status= 4;
        } else {
            //return "time_five";
            status= 5;
        }
        return status;
    }

    @Override
    public void delete(Long id) {
        log.debug("删除预约业务,id:{}",id);
        reservationMapper.deleteReservationById(id);
    }
}
